package com.hzzftech.watchdog.busi.controller;

import com.hzzftech.watchdog.busi.constants.BusiConstant;

import com.hzzftech.watchdog.busi.core.dance.JobChangeState;
import com.hzzftech.watchdog.busi.domain.*;
import com.hzzftech.watchdog.busi.mapper.KtJobMapper;
import com.hzzftech.watchdog.busi.service.*;
import com.hzzftech.watchdog.common.annotation.Log;
import com.hzzftech.watchdog.common.core.controller.BaseController;
import com.hzzftech.watchdog.common.core.domain.AjaxResult;
import com.hzzftech.watchdog.common.core.domain.entity.SysDictData;
import com.hzzftech.watchdog.common.core.domain.entity.SysUser;
import com.hzzftech.watchdog.common.core.page.TableDataInfo;
import com.hzzftech.watchdog.common.core.text.Convert;
import com.hzzftech.watchdog.common.enums.BusinessType;
import com.hzzftech.watchdog.common.utils.poi.ExcelUtil;
import com.hzzftech.watchdog.framework.web.domain.server.Sys;
import com.hzzftech.watchdog.system.service.ISysDictDataService;
import com.hzzftech.watchdog.system.service.ISysUserService;
import org.apache.commons.codec.binary.Base64;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.pentaho.di.core.exception.KettleMissingPluginsException;
import org.pentaho.di.core.exception.KettleXMLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.Objects;

/**
 * 任务调度Controller
 *
 * @author liquanxiang
 * @date 2021-12-14
 */
@Controller
@RequestMapping("/busi/dispatcher")
public class KtDispatcherController extends BaseController
{
    private String prefix = "busi/dispatcher";

    @Autowired
    private IKtDispatcherService ktDispatcherService;

    @Autowired
    private IKtFileRepositoryService frepositoryService;

    @Autowired
    private IKtRepositoryService grepositoryService;

    @Autowired
    private IKtRepositoryNodeService iKtRepositoryNodeService;

    @Autowired
    private IKtParamsGroupService iKtParamsGroupService;

    @Autowired
    private IKtWarnMsgService warnMsgService;


    @Autowired
    private ISysDictDataService dictService;

    @RequiresPermissions("busi:dispatcher:view")
    @GetMapping()
    public String dispatcher()
    {
        return prefix + "/dispatcher";
    }

    @RequiresPermissions("busi:dispatcher:view")
    @GetMapping("/jobSelect")
    public String jobSelect()
    {
        return "busi/job/dispatcher";
    }

    @RequiresPermissions("busi:dispatcher:view")
    @GetMapping("/monitor")
    public String dispatcherMonitor()
    {
        return "busi/monitor/dispatcherMonitor";
    }

    /**
     * 查询任务调度列表
     */
    @RequiresPermissions("busi:dispatcher:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(KtDispatcher ktDispatcher, ModelMap mmap)
    {
        startPage();

        if (ktDispatcher.getDpRepoType() == null) {
            ktDispatcher.setDpRepoType(BusiConstant.REPOSITORY_TYPE_GIT);
        }
        List<KtDispatcher> list = ktDispatcherService.selectKtDispatcherList(ktDispatcher, ktDispatcher.getDpRepoType());

        return getDataTable(list);
    }

    /**
     * 查询任务调度列表
     */
    @RequiresPermissions("busi:dispatcher:list")
    @PostMapping("/listMonitor")
    @ResponseBody
    public TableDataInfo listMonitor(KtDispatcher ktDispatcher, ModelMap mmap)
    {
        startPage();

        if (ktDispatcher.getDpRepoType() == null) {
            ktDispatcher.setDpRepoType(BusiConstant.REPOSITORY_TYPE_GIT);
        }
        List<KtDispatcher> list = ktDispatcherService.selectKtDispatcherList(ktDispatcher, ktDispatcher.getDpRepoType());

        for (KtDispatcher dispatcher : list) {
             ktDispatcherService.selectKtDispatcherForMonitor(dispatcher);
        }

        return getDataTable(list);
    }

    /**
     * 导出任务调度列表
     */
    @RequiresPermissions("busi:dispatcher:export")
    @Log(title = "任务调度", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(KtDispatcher ktDispatcher)
    {
        List<KtDispatcher> list = ktDispatcherService.selectKtDispatcherList(ktDispatcher, ktDispatcher.getDpRepoType());
        ExcelUtil<KtDispatcher> util = new ExcelUtil<KtDispatcher>(KtDispatcher.class);
        return util.exportExcel(list, "任务调度数据");
    }

    @Autowired
    private ISysUserService userService;

    /**
     * 新增任务调度
     */
    @GetMapping("/add/{dpRepoType}")
    public String add(@PathVariable("dpRepoType") String repoType, ModelMap mmap)
    {
        KtFileRepository repository = new KtFileRepository();
        List<KtFileRepository> frepoList = frepositoryService.selectKtFileRepositoryList(repository);
        // 资源仓库
        mmap.addAttribute("repoListF", frepoList);
        KtRepository repository1 = new KtRepository();
        List<KtRepository> ktRepositories = grepositoryService.selectKtRepositoryList(repository1);
        mmap.addAttribute("repoListG", ktRepositories);
        SysDictData dictQObj = new SysDictData();
        dictQObj.setDictType("task_type");

        mmap.put("taskType", dictService.selectDictDataList(dictQObj));

        mmap.addAttribute("dpRepoType", repoType);


        KtRepositoryNode node = new KtRepositoryNode();
        node.setStatus(BusiConstant.STATUS_YES);
        List<KtRepositoryNode> ktRepositoryNodes = iKtRepositoryNodeService.selectKtRepositoryNodeList(node);
        // 服务器节点
        mmap.addAttribute("nodeList", ktRepositoryNodes);
        KtParamsGroup group = new KtParamsGroup();
        group.setStatus(BusiConstant.STATUS_YES);
        List<KtParamsGroup> ktParamsGroups = iKtParamsGroupService.selectKtParamsGroupList(group);
        // 运行参数
        mmap.addAttribute("pgList", ktParamsGroups);
//        List<KtWarnMsg> ktWarnMsgs = warnMsgService.selectKtWarnMsgList(new KtWarnMsg());
        // 发送警告信息
        SysUser user = new SysUser();
        user.setDeptId(110L);
        user.setStatus(BusiConstant.STATUS_YES);
        mmap.addAttribute("warnList", userService.selectUserList(user));

        return prefix + "/add";
    }

    /**
     * 新增保存任务调度
     */
    @RequiresPermissions("busi:dispatcher:add")
    @Log(title = "任务调度", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(KtDispatcher ktDispatcher)
    {
        KtDispatcher dispatcher = ktDispatcherService.selectKtDispatcherByDpName(ktDispatcher.getDpName());
        if (!Objects.isNull(dispatcher)) {
            return AjaxResult.error("调度名称重复！");
        }

        ktDispatcherService.addProcess(ktDispatcher);

        int k = ktDispatcherService.insertKtDispatcher(ktDispatcher);
        if (k == -1) {
            return AjaxResult.error("调度必须为kjb或者ktr文件");
        }
        // 触发监控更新
        JobChangeState.instance.jobStateChange();
        return toAjax(k);
    }

    /**
     * 修改任务调度
     */
    @RequiresPermissions("busi:dispatcher:edit")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap)
    {
        KtDispatcher ktDispatcher = ktDispatcherService.selectKtDispatcherById(id, BusiConstant.REPOSITORY_TYPE_FILE);
        // 调度信息
        mmap.put("ktDispatcher", ktDispatcher);

        KtRepositoryNode node = new KtRepositoryNode();
        node.setStatus(BusiConstant.STATUS_YES);
        List<KtRepositoryNode> ktRepositoryNodes = iKtRepositoryNodeService.selectKtRepositoryNodeList(node);
        // 服务器节点
        mmap.addAttribute("nodeList", ktRepositoryNodes);
        KtParamsGroup group = new KtParamsGroup();
        group.setStatus(BusiConstant.STATUS_YES);
        List<KtParamsGroup> ktParamsGroups = iKtParamsGroupService.selectKtParamsGroupList(group);
        // 发送预警信息
        mmap.addAttribute("pgList", ktParamsGroups);
        SysUser user = new SysUser();
        user.setDeptId(110L);
        user.setStatus(BusiConstant.STATUS_YES);
        mmap.addAttribute("warnList", userService.selectUserList(user));
        return prefix + "/edit";
    }

    /**
     * 修改保存任务调度
     */
    @RequiresPermissions("busi:dispatcher:edit")
    @Log(title = "任务调度", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(KtDispatcher ktDispatcher)
    {
        ktDispatcherService.updateProcess(ktDispatcher);
        // 触发监控更新
        JobChangeState.instance.jobStateChange();
        return toAjax(ktDispatcherService.updateKtDispatcher(ktDispatcher));
    }

    @Autowired
    private KtJobMapper jobMapper;

    /**
     * 删除任务调度
     */
    @RequiresPermissions("busi:dispatcher:remove")
    @Log(title = "任务调度", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        int count = 0;
        for (String id : Convert.toStrArray(ids)) {
            Long _id = Long.parseLong(id);
            List<KtJob> jobs = jobMapper.selectByDpId(_id);

            if (!jobs.isEmpty()) {
                return AjaxResult.error("删除失败，有定时任务引用了该任务调度");
            }

            ktDispatcherService.deleteKtDispatcherById(_id);
            count++;
        }
        // 触发监控更新
        JobChangeState.instance.jobStateChange();
        return toAjax(count);
    }

    @RequiresPermissions("busi:dispatcher:launch")
    @Log(title = "git仓库任务调度", businessType = BusinessType.OTHER)
    @PostMapping( "/launchG")
    @ResponseBody
    public AjaxResult startGJobOrTrans(String ids) throws KettleMissingPluginsException, KettleXMLException {
        return toAjax(ktDispatcherService.launchGJob(ids));
    }

    @RequiresPermissions("busi:dispatcher:launch")
    @Log(title = "文件仓库任务调度", businessType = BusinessType.OTHER)
    @PostMapping( "/launchF")
    @ResponseBody
    public AjaxResult startFJobOrTrans(String ids) throws KettleMissingPluginsException, KettleXMLException {
        return toAjax(ktDispatcherService.launchFJob(ids, null));
    }

    @Autowired
    private IKtExecutionLogService logService;

    @Value("${kt-watchdog.file_repository_location}")
    private String LOG_FILE;

    @RequiresPermissions("busi:dispatcher:log")
    @Log(title = "任务调度日志文件", businessType = BusinessType.OTHER)
    @GetMapping( "/img")
    @ResponseBody
    public AjaxResult getKtImg(@RequestParam("id") String id) {
        /**
         * 用于获取任务调度的执行图片信息，由carte服务生成
         */
        KtExecutionLog log = logService.selectKtExecutionLogById(id);
        String logFPath = "";
        if (log.getTaskType().equals(BusiConstant.KETTLE_TYPE_FLAG_TRANS)) {
            logFPath = LOG_FILE + "/trans/"+log.getImagePath();
        } else if (log.getTaskType().equals(BusiConstant.KETTLE_TYPE_FLAG_JOB)){
            logFPath = LOG_FILE + "/job/"+log.getImagePath();
        }
        File f = new File(logFPath);
        if (!f.exists()) {
            return AjaxResult.error();
        }

        try {
            FileInputStream in = new FileInputStream(f);
            long size = f.length();
            byte[] buffer = new byte[(int)size];
            in.read(buffer, 0, (int)size);
            in.close();
            AjaxResult success = AjaxResult.success();
            success.put("image", Base64.encodeBase64String(buffer));
            return success;
        } catch (Exception e) {
            logger.error("读写文件错误",e);
            return AjaxResult.error("读写文件错误");
        }
    }

    @Autowired
    private IKtJobService ktJobService;

    @RequiresPermissions("busi:dispatcher:changeStatus")
    @Log(title = "修改状态", businessType = BusinessType.UPDATE)
    @PostMapping( "/changeStatus")
    @ResponseBody
    public AjaxResult changeStatus(KtDispatcher ktDispatcher) {
        KtDispatcher dispatcher = ktDispatcherService.selectKtDispatcherById(ktDispatcher.getId());
        dispatcher.setStatus(ktDispatcher.getStatus());
        if (dispatcher.getStatus().equals(BusiConstant.STATUS_NO)) {
            KtJob job = new KtJob();
            job.setDpId(ktDispatcher.getId());
            List<KtJob> ktJobs = ktJobService.selectJobList(job);
            try {
                for (KtJob j : ktJobs) {
                    ktJobService.pauseJob(j);
                }
            } catch (Exception e) {
                logger.error("暂停定时任务出错", e);
            }
        }
        // 触发监控更新
        JobChangeState.instance.jobStateChange();
        return toAjax(ktDispatcherService.updateKtDispatcher(dispatcher));
    }
}
